今天是XXE課程第4步的練習,今天的練習跟昨天的有點類似,只是今天的挑戰要特別說明現代人愛用的REST架構可能會遇到的XXE Injection風險。
表現層狀態轉換 (Representational State Transfer, REST)架構住要拿來作為網頁前後端的資料傳輸時,而又常使用JSON格式作為資料請求與回應的格式,例如這次的練習就一個例子,我們在網頁輸入框輸入「TEST」並送出後,使用ZAP擷取到瀏覽器是將我們輸入的內容以JSON格式送出,如下圖所示。
但後端在接收JSON的時候並沒有再次驗證從前端送過來的資料格式及內容,導致我們只要把HTTP Header中的「Content-Type」由「application/json」改為「application/xml」,並把跟昨天練習一樣的XML內容送過去,就可以讓後端吐出不該吐的資料。
如此一來,我們的資料夾列表又被吐出來啦。
至於要如何預防XXE Injection發生呢?最好的方法就是對於瀏覽器傳到伺服器的每個請求都再次進行驗證,我們都知道前端的過濾只能防一般人,且很容易被竄改,因此後端應該要再次確認,才能確保不會執行到預料外的指令。
以Java為例,下列的程式碼可以讓你的程式避免執行到DTD。
XMLInputFactory xif = XMLInputFactory.newFactory();
xif.setProperty(XMLInputFactory.SUPPORT_DTD, false);
但如果你必須用到DTD,則至少可以用下面的程式碼來避免外部實體,以免不該洩漏的資訊被參照到。
XMLInputFactory xif = XMLInputFactory.newFactory();
xif.setProperty(XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES, false);
xif.setProperty(XMLInputFactory.SUPPORT_DTD, true);
最後,在HTTP Header的部分也需要注意,尤其「Content-type」及「Accept」兩個欄位很容易被竄改為有利攻擊者的內容,因此也可以在伺服器端再次做驗證才是安全的作法。
參考資料:
[1] https://www.owasp.org/index.php/XML_External_Entity_(XXE)_Prevention_Cheat_Sheet